package com.scholarship.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scholarship.system.common.dto.Result;
import com.scholarship.system.entity.PoliticalPerformance;
import com.scholarship.system.entity.ResearchAbility;
import com.scholarship.system.entity.Student;
import com.scholarship.system.entity.StudentRanking;
import com.scholarship.system.mapper.PoliticalMapper;
import com.scholarship.system.mapper.RankingMapper;
import com.scholarship.system.mapper.ResearchMapper;
import com.scholarship.system.mapper.StudentMapper;
import com.scholarship.system.service.RankingService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 排名服务实现类
 */
@Service
public class RankingServiceImpl extends ServiceImpl<RankingMapper, StudentRanking> implements RankingService {

    private static final Logger logger = LoggerFactory.getLogger(RankingServiceImpl.class);

    @Autowired
    private RankingMapper rankingMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private PoliticalMapper politicalMapper;

    @Autowired
    private ResearchMapper researchMapper;

    @Override
    @Transactional
    public Result<Void> generateRanking(Integer year, String semester) {
        try {
            // 设置默认值
            if (year == null) {
                year = Year.now().getValue();
            }
            if (semester == null || semester.isEmpty()) {
                int month = LocalDate.now().getMonthValue();
                semester = month >= 2 && month <= 7 ? "春季" : "秋季";
            }

            // 1. 清空当前学期的排名数据
            LambdaQueryWrapper<StudentRanking> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(StudentRanking::getYear, year)
                    .eq(StudentRanking::getSemester, semester);
            remove(deleteWrapper);

            // 2. 获取所有学生
            List<Student> students = studentMapper.selectList(null);
            List<StudentRanking> rankings = new ArrayList<>();

            // 3. 遍历学生，获取其思政和科研得分
            for (Student student : students) {
                StudentRanking ranking = new StudentRanking();
                ranking.setStudentId(student.getId());
                ranking.setCollege(student.getCollege());
                ranking.setMajor(student.getMajor());
                ranking.setGrade(student.getGrade());
                ranking.setClassName(student.getClassName());
                ranking.setYear(year);
                ranking.setSemester(semester);

                // 获取思政得分
                LambdaQueryWrapper<PoliticalPerformance> politicalWrapper = new LambdaQueryWrapper<>();
                politicalWrapper.eq(PoliticalPerformance::getStudentId, student.getId())
                        .eq(PoliticalPerformance::getYear, year)
                        .eq(PoliticalPerformance::getSemester, semester);
                PoliticalPerformance politicalPerformance = politicalMapper.selectOne(politicalWrapper);
                if (politicalPerformance != null && politicalPerformance.getTotalScore() != null) {
                    ranking.setPoliticalScore(politicalPerformance.getTotalScore());
                } else {
                    ranking.setPoliticalScore(BigDecimal.ZERO);
                }

                // 获取科研得分
                LambdaQueryWrapper<ResearchAbility> researchWrapper = new LambdaQueryWrapper<>();
                researchWrapper.eq(ResearchAbility::getStudentId, student.getId())
                        .eq(ResearchAbility::getYear, year)
                        .eq(ResearchAbility::getSemester, semester);
                ResearchAbility researchAbility = researchMapper.selectOne(researchWrapper);
                if (researchAbility != null && researchAbility.getTotalScore() != null) {
                    ranking.setResearchScore(researchAbility.getTotalScore());
                } else {
                    ranking.setResearchScore(BigDecimal.ZERO);
                }

                // 添加到列表
                rankings.add(ranking);
            }

            // 4. 批量保存排名数据
            saveBatch(rankings);

            // 5. 更新排名
            rankingMapper.updateRanking(year, semester);

            return Result.success();
        } catch (Exception e) {
            logger.error("生成排名异常", e);
            return Result.error("生成排名失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<Map<String, Object>>> getRankingList(String college, String major, String grade, String keyword,
            Integer year, String semester) {
        try {
            // 设置默认值
            if (year == null) {
                year = Year.now().getValue();
            }
            if (semester == null || semester.isEmpty()) {
                int month = LocalDate.now().getMonthValue();
                semester = month >= 2 && month <= 7 ? "春季" : "秋季";
            }

            // 查询排名列表
            List<Map<String, Object>> rankingList = rankingMapper.selectRankingList(college, major, grade, keyword,
                    year, semester);
            return Result.success(rankingList);
        } catch (Exception e) {
            logger.error("获取排名列表异常", e);
            return Result.error("获取排名列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Void> exportRankingToExcel(String college, String major, String grade, String keyword, Integer year,
            String semester, HttpServletResponse response) {
        Workbook workbook = null;
        try {
            // 设置默认值
            if (year == null) {
                year = Year.now().getValue();
            }
            if (semester == null || semester.isEmpty()) {
                int month = LocalDate.now().getMonthValue();
                semester = month >= 2 && month <= 7 ? "春季" : "秋季";
            }

            logger.debug("开始导出排名Excel, 参数: college={}, major={}, grade={}, keyword={}, year={}, semester={}",
                    college, major, grade, keyword, year, semester);

            // 查询排名列表
            List<Map<String, Object>> rankingList = rankingMapper.selectRankingList(college, major, grade, keyword,
                    year, semester);

            logger.debug("查询到{}条排名数据", rankingList.size());

            // 创建工作簿和工作表 - 使用XSSF而不是SXSSFWorkbook，减少内存使用
            workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("学生综合排名");

            // 创建标题样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);

            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = { "排名", "学号", "姓名", "学院", "专业", "年级", "班级", "思政表现得分", "科研能力得分", "总分" };
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
                sheet.setColumnWidth(i, 15 * 256); // 设置列宽
            }

            // 填充数据
            int rowNum = 1;
            for (Map<String, Object> ranking : rankingList) {
                Row row = sheet.createRow(rowNum++);

                // 排名
                if (ranking.get("rank") != null) {
                    try {
                        row.createCell(0).setCellValue(Integer.parseInt(ranking.get("rank").toString()));
                    } catch (NumberFormatException e) {
                        row.createCell(0).setCellValue(0);
                        logger.warn("排名数据转换异常: {}", e.getMessage());
                    }
                } else {
                    row.createCell(0).setCellValue(0);
                }

                // 学号
                row.createCell(1)
                        .setCellValue(ranking.get("student_no") != null ? ranking.get("student_no").toString() : "");

                // 姓名
                row.createCell(2).setCellValue(ranking.get("name") != null ? ranking.get("name").toString() : "");

                // 学院
                row.createCell(3).setCellValue(ranking.get("college") != null ? ranking.get("college").toString() : "");

                // 专业
                row.createCell(4).setCellValue(ranking.get("major") != null ? ranking.get("major").toString() : "");

                // 年级
                row.createCell(5).setCellValue(ranking.get("grade") != null ? ranking.get("grade").toString() : "");

                // 班级
                row.createCell(6)
                        .setCellValue(ranking.get("class_name") != null ? ranking.get("class_name").toString() : "");

                // 思政表现得分
                if (ranking.get("political_score") != null) {
                    try {
                        row.createCell(7).setCellValue(Double.parseDouble(ranking.get("political_score").toString()));
                    } catch (NumberFormatException e) {
                        row.createCell(7).setCellValue(0);
                        logger.warn("思政得分数据转换异常: {}", e.getMessage());
                    }
                } else {
                    row.createCell(7).setCellValue(0);
                }

                // 科研能力得分
                if (ranking.get("research_score") != null) {
                    try {
                        row.createCell(8).setCellValue(Double.parseDouble(ranking.get("research_score").toString()));
                    } catch (NumberFormatException e) {
                        row.createCell(8).setCellValue(0);
                        logger.warn("科研得分数据转换异常: {}", e.getMessage());
                    }
                } else {
                    row.createCell(8).setCellValue(0);
                }

                // 总分
                if (ranking.get("total_score") != null) {
                    try {
                        row.createCell(9).setCellValue(Double.parseDouble(ranking.get("total_score").toString()));
                    } catch (NumberFormatException e) {
                        row.createCell(9).setCellValue(0);
                        logger.warn("总分数据转换异常: {}", e.getMessage());
                    }
                } else {
                    row.createCell(9).setCellValue(0);
                }
            }

            // 设置响应头
            String fileName = URLEncoder.encode("学生综合排名_" + year + "_" + semester, StandardCharsets.UTF_8.toString());
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");

            // 禁用缓存
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");

            // 设置响应长度
            // 先将Excel写入字节数组
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            workbook.write(baos);
            byte[] excelBytes = baos.toByteArray();
            baos.close();

            response.setContentLength(excelBytes.length);

            logger.debug("开始写入Excel到响应流，文件大小: {} 字节", excelBytes.length);

            // 一次性写入
            response.getOutputStream().write(excelBytes);
            response.getOutputStream().flush();

            logger.debug("Excel导出完成");

            return Result.success();
        } catch (Exception e) {
            logger.error("导出排名Excel异常", e);
            try {
                // 如果响应已经提交，则无法再写入错误信息
                if (!response.isCommitted()) {
                    response.reset();
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.getWriter().write("{\"code\":500,\"msg\":\"导出排名Excel失败: " + e.getMessage() + "\"}");
                    response.getWriter().flush();
                }
            } catch (IOException ex) {
                logger.error("写入错误响应异常", ex);
            }
            return Result.error("导出排名Excel失败: " + e.getMessage());
        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    logger.error("关闭工作簿异常", e);
                }
            }
        }
    }

    @Override
    public Result<List<String>> getCollegeList() {
        try {
            List<String> collegeList = rankingMapper.selectCollegeList();
            return Result.success(collegeList);
        } catch (Exception e) {
            logger.error("获取学院列表异常", e);
            return Result.error("获取学院列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<String>> getMajorListByCollege(String college) {
        try {
            List<String> majorList = rankingMapper.selectMajorListByCollege(college);
            return Result.success(majorList);
        } catch (Exception e) {
            logger.error("获取专业列表异常", e);
            return Result.error("获取专业列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<String>> getGradeListByMajor(String major) {
        try {
            List<String> gradeList = rankingMapper.selectGradeListByMajor(major);
            return Result.success(gradeList);
        } catch (Exception e) {
            logger.error("获取年级列表异常", e);
            return Result.error("获取年级列表失败: " + e.getMessage());
        }
    }
}